﻿using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.Common;
using KWT.DRG_DIP.DB;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.DTO.Basic.Tenant;
using KWT.DRG_DIP.PO.Basic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace KWT.DRG_DIP.API.Controllers.Basic
{
    /// <summary>
    /// 租户管理
    /// </summary>
    [ApiExplorerSettings(GroupName = "basic")]
    public class TenantController : BasicControllerBase
    {
        public MainEFContext main { get; set; }
        /// <summary>
        /// 分页列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<PageList<OutPageList>>), 200)]
        public OutputResult List(InPageList dto)
        {
            var q = main.Set<Sys_Tenant>().AsQueryable();

            if (!string.IsNullOrEmpty(dto.Name))
            {
                q = q.Where(x => EF.Functions.Like(x.Name, $"%{dto.Name}%"));
            }
            if (!string.IsNullOrEmpty(dto.City))
            {
                q = q.Where(x => x.City == dto.City);
            }
            if (!string.IsNullOrEmpty(dto.Province))
            {
                q = q.Where(x => x.Province == dto.Province);
            }
            if (!string.IsNullOrEmpty(dto.County))
            {
                q = q.Where(x => x.County == dto.County);
            }
            q = q.Where(x => x.TenantID != "main");
            var total = q.Count();
            var list = q.Select(x =>
            new OutPageList()
            {
                CityName = x.CityName,
                ConnStr = x.ConnStr,
                CountyName = x.CountyName,
                Icon = x.Icon,
                Name = x.Name,
                ProvinceName = x.ProvinceName,
                TenantID = x.TenantID
            }).ToPageList(dto.PageNo, dto.PageSize);
            return Output(list != null, "", "", new PageList<OutPageList>() { List = list, Total = total });
        }

        /// <summary>
        /// 添加或编辑
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<string>), 200)]
        public OutputResult AddOrUpdate(InAddOrUpdate dto)
        {
            var tenant = _mapper.Map<Sys_Tenant>(dto);
            var p_name = _Config.GetValue<string>($"City:86:{dto.Province}");
            if (string.IsNullOrWhiteSpace(dto.TenantID))
            {
                tenant.TenantID = _Tool.RandomString(8);
                tenant.ProvinceName = p_name;
                main.Add(tenant);
                var areas = new List<Tenant_Area>();
                foreach (var item in dto.TenantAreas)
                {
                    areas.Add(new Tenant_Area() { TenantID = tenant.TenantID, Name = item.Name, Code = item.Code, AreaID = "AR" + snow_id.CreateId().ToString() });
                }
                main.AddRange(areas);
                var modules = new List<Module_Tenant>();
                foreach (var item in dto.ModuleIDs)
                {
                    modules.Add(new Module_Tenant() { MTID = "MT" + snow_id.CreateId().ToString(), ModuleID = item, TenantID = tenant.TenantID });
                }
                main.AddRange(modules);
            }
            else
            {
                var areas = main.Set<Tenant_Area>().Where(x => x.TenantID == dto.TenantID).ToList();
                main.RemoveRange(areas);
                main.SaveChanges();
                var _areas = new List<Tenant_Area>();
                foreach (var item in dto.TenantAreas)
                {
                    if (string.IsNullOrEmpty(item.AreaID))
                    {
                        _areas.Add(new Tenant_Area() { TenantID = tenant.TenantID, Name = item.Name, Code = item.Code, AreaID = "AR" + snow_id.CreateId().ToString() });
                    }
                    else
                    {
                        _areas.Add(new Tenant_Area() { TenantID = tenant.TenantID, Name = item.Name, Code = item.Code, AreaID = item.AreaID });
                    }
                }
                main.AddRange(_areas);

                var modules = main.Set<Module_Tenant>().Where(x => x.TenantID == dto.TenantID).ToList();
                main.RemoveRange(modules);
                var _modules = new List<Module_Tenant>();
                foreach (var item in dto.ModuleIDs)
                {

                    _modules.Add(new Module_Tenant() { MTID = "MT" + snow_id.CreateId().ToString(), ModuleID = item, TenantID = dto.TenantID });

                }
                main.AddRange(_modules);


                var _tenant = main.Find<Sys_Tenant>(dto.TenantID);
                _tenant.Name = tenant.Name;
                _tenant.City = tenant.City;
                _tenant.CityName = tenant.CityName;
                _tenant.Province = tenant.Province;
                _tenant.ProvinceName = p_name;
                _tenant.Code = tenant.Code;
                _tenant.ConnStr = tenant.ConnStr;
                _tenant.UpdTime = DateTime.Now;
                _tenant.UsePolicy = tenant.UsePolicy;
                main.Attach(_tenant);
            }
            var flag = main.SaveChanges() > 0;
            return Output(flag, "操作成功", "操作失败");
        }

        /// <summary>
        /// 禁用/启用
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<string>), 200)]
        public OutputResult Del(InDel dto)
        {
            var tenant = main.Find<Sys_Tenant>(dto.TenantID);
            if (tenant == null)
            {
                return Fail("未找到该项");
            }
            tenant.IsDel = dto.Status == 1;
            main.Attach(tenant);
            var flag = main.SaveChanges() > 0;
            return Output(flag, "操作成功", "操作失败");
        }

        /// <summary>
        /// 折叠列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public OutputResult TreeList(InTreeList dto)
        {
            var q = main.Set<Sys_Tenant>().AsQueryable();
            if (!string.IsNullOrEmpty(dto.Name))
            {
                q = q.Where(x => EF.Functions.Like(x.Name, $"%{dto.Name}%"));
            }
            if (!string.IsNullOrEmpty(dto.Province))
            {
                q = q.Where(x => x.Province == dto.Province);
            }
            if (!string.IsNullOrEmpty(dto.City))
            {
                q = q.Where(x => x.City == dto.City);
            }
            var all = q.Where(x => x.TenantID != "main").ToList();
            var province = all.Select(x => new { x.Province, x.City, x.ProvinceName, x.UsePolicy, x.IsDel }).DistinctBy(x => x.Province);
            var city = all.Select(x => new { x.Province, x.City, x.CityName, x.UsePolicy, x.IsDel }).DistinctBy(x => x.City);
            var list = new List<OutTreeList>();
            foreach (var item in province)
            {
                var outTree = new OutTreeList() { TenantID = snow_id.CreateId().ToString(), Name = item.ProvinceName, City = item.City };

                foreach (var y in city)
                {
                    if (item.Province[..2] == y.City[..2])
                    {
                        var child = new OutTreeList() { TenantID = snow_id.CreateId().ToString(), Name = y.CityName, City = y.City };
                        outTree.Children.Add(child);
                        foreach (var x in all)
                        {
                            if (y.City[..4] == x.City[..4])
                            {
                                var modules = (from a in main.Set<Sys_Module>().AsQueryable()
                                               join b in main.Set<Module_Tenant>().AsQueryable() on a.ModuleID equals b.ModuleID
                                               where b.TenantID == x.TenantID
                                               select new { a.ModuleID, a.Name }).AsNoTracking().ToList();

                                var tenantArea = new List<TenantArea>();

                                var area = main.Set<Tenant_Area>().Where(z => z.TenantID == x.TenantID).AsNoTracking().ToList();
                                foreach (var items in area)
                                {

                                    tenantArea.Add(new TenantArea() { AreaID = items.AreaID, Code = items.Code, Name = items.Name, Index = area.IndexOf(items) });
                                }

                                var _child = new OutTreeList()
                                {
                                    Name = x.Name,
                                    Province = x.Province,
                                    ProvinceName = x.ProvinceName,
                                    City = x.City,
                                    TenantID = x.TenantID,
                                    CityName = x.CityName,
                                    ConnStr = x.ConnStr,
                                    Code = x.Code,
                                    AddTime = x.AddTime,
                                    UpdTime = x.UpdTime,
                                    UsePolicy = x.UsePolicy,
                                    ModuleName = string.Join(',', modules.Select(x => x.Name)),
                                    ModuleIDs = modules.Select(x => x.ModuleID).ToArray(),
                                    TenantArea = tenantArea,
                                    IsDel = x.IsDel,
                                    _showChildren = true
                                };
                                child.Children.Add(_child);
                            }
                        }
                    }
                }


                list.Add(outTree);
            }
            return Output(list.Count > 0, "", "", list);
        }

        /// <summary>
        /// 根据租户号得到院区
        /// </summary>
        /// <param name="tenantID"></param>
        /// <returns></returns>
        [HttpGet]
        public OutputResult GetAreas([FromQuery] string tenantID)
        {
            var list = main.Set<Tenant_Area>().Where(x => x.TenantID == tenantID).Select(x => new { index = x.AreaID, value = x.Name, status = 1 }).ToList();
            return Output(list.Count > 0, "", "", list);
        }
    }
}
